package com.hmkj.web.controller.pay;

import com.hmkj.common.entity.ResultEntity;
import com.hmkj.common.utils.OrderNoUtils;
import com.hmkj.core.api.hrpay.HRPayUtils;
import com.hmkj.core.api.hrpay.utils.ConfigUtils;
import com.hmkj.core.api.hrpay.utils.SignUtils;
import com.hmkj.core.constant.CacheID;
import com.hmkj.core.constant.ConfigNID;
import com.hmkj.core.exception.BussinessException;
import com.hmkj.core.po.amount.Recharge;
import com.hmkj.core.po.system.Bank;
import com.hmkj.core.po.user.User;
import com.hmkj.core.po.user.UserBank;
import com.hmkj.core.service.amount.RechargeService;
import com.hmkj.core.service.system.BankService;
import com.hmkj.core.service.user.UserBankService;
import com.hmkj.core.service.user.UserService;
import com.hmkj.web.controller.GenericController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 华融支付
 *
 * @author Vector
 * @create 2018-01-15 21:22
 */
@Api(description = "华融支付")
@Slf4j
@RestController
@RequestMapping(GenericController.MEMBER_URL + "/pay/hr")
public class HRPayController extends GenericController<Integer, Recharge> {

    @Resource
    private UserService userService;

    @Resource
    private BankService bankService;

    @Resource
    private UserBankService userBankService;

    @Resource
    private RechargeService rechargeService;


    /**
     * 快捷支付第一步-发送验证码
     *
     * @param bankId 银行ID
     * @param amount 充值金额
     */
    @ApiOperation(value = "快捷支付第一步-发送验证码", notes = "快捷支付第一步-发送验证码")
    @ResponseBody
    @RequestMapping(value = "/authentication", method = RequestMethod.POST)
    public ResultEntity authentication(@ApiParam("银行ID") @RequestParam Integer bankId,
                                       @ApiParam("充值金额") @RequestParam BigDecimal amount) throws Exception {
        String notifyUrl = redisService.get(ConfigNID.WEB_SERVER_URL) + "api/notify/hr/doNotify";
        User user = userService.selectByPrimaryKey(getLoginUser().getId());
        if (user == null) throw new BussinessException("查询用户信息失败");

        UserBank bank = userBankService.selectByPrimaryKey(bankId);
        if (bank == null) throw new BussinessException("查询充值银行卡失败");

        // 发送短信验证码
        try {
            Map<String, String> resDataMap = HRPayUtils.authentication(amount, notifyUrl, user.getRealName(), bank.getMobile(),
                    user.getIdCard(), bank.getBankNo(), bank.getExpireDate(), bank.getCvn2());

            if (!("0000".equals(resDataMap.get("respCode")) || "P000".equals(resDataMap.get("respCode"))))
                throw new BussinessException(resDataMap.get("respDesc"));

            // 缓存充值订单号
            redisService.put(CacheID.HR_PAY_RECHARGE + getLoginUser().getId(), resDataMap);
        } catch (BussinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BussinessException("系统繁忙，请稍后再试");
        }

        return ok("发送短信成功");
    }


    /**
     * 快捷支付第二步-支付
     *
     * @param checkCode 验证码
     */
    @ApiOperation(value = "快捷支付提交", notes = "快捷支付提交")
    @ResponseBody
    @RequestMapping(value = "/quickPay", method = RequestMethod.POST)
    public ResultEntity quickPay(@ApiParam("验证码") @RequestParam String checkCode) throws Exception {
        rechargeService.doRechargeByHR(getLoginUser().getId(), checkCode);
        return ok("支付提交成功");
    }

    /**
     * 网银B2C支付
     *
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "网银B2C", notes = "网银B2C")
    @ResponseBody
    @RequestMapping(value = "/b2cPay", method = RequestMethod.POST)
    public ResultEntity b2cPay(@ApiParam("银行ID") @RequestParam Integer bankId ,@ApiParam("充值金额") @RequestParam BigDecimal amount ,HttpServletResponse response) throws Exception {
        String html = null;
        try {
            String bankCode = outCode2innerCode4nInepayHR(bankId.intValue());
            String orderNo = OrderNoUtils.getHRCashOrderNo();
            String TransAmt = amount.multiply(BigDecimal.valueOf(100)).toString();
            Map<String, String> map = getMapValues(orderNo,bankCode,TransAmt);
            html = buildHtmlForm(map,ConfigUtils.getProperty("trans_url"));
            rechargeService.doRechargeByHRB2C(getLoginUser().getId(),bankId,map);
        } catch (BussinessException e) {
            e.printStackTrace();
            throw new BussinessException(e.getMessage());
        }
        response.reset();
        response.setContentType("text/html;charset=utf-8");
        OutputStream os = response.getOutputStream();
        os.write(html.getBytes("UTF-8"));
        os.flush();
        os.close();
//        PrintWriter out = response.getWriter();
//        out.println(html);
//        out.flush();
//        out.close();
        return ok();
    }

    /**
     * 网银B2C银行列表
     *
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "网银B2C银行列表", notes = "网银B2C银行列表")
    @ResponseBody
    @RequestMapping(value = "/b2cBankList", method = RequestMethod.POST)
    public ResultEntity b2cBankList() throws Exception {
        String ids = "1,2,3,4,5,7,8,10,11,12,13,17,18,20,21,22,24,25,28,29,30,69,84,90,91";
         List<Bank> banks = bankService.selectByIds(ids);
        return ok(banks);
    }

    private  String buildForm(Map<String, String> sParaTemp, String gateway) {
        // 待请求参数数组
        Set<String> keys = sParaTemp.keySet();

        StringBuffer sbHtml = new StringBuffer();

        sbHtml.append("<form id=\"editForm\" name=\"editForm\" action=\"");
        sbHtml.append(gateway);
        sbHtml.append("\" method=\"");
        sbHtml.append("POST");
        sbHtml.append("\">");
        for (String name : keys) {
            String value = sParaTemp.get(name);
            sbHtml.append("<input type=\"hidden\" name=\"");
            sbHtml.append(name == null ? name : name.trim());
            sbHtml.append("\" value=\"");
            sbHtml.append(value == null ? value : value.trim());
            sbHtml.append("\"/>");
        }
        // submit按钮控件请不要含有name属性
        sbHtml.append("<input type=\"submit\" value=\"充值\" style=\"display:none;\"></form>");
        sbHtml.append("<script>document.forms['editForm'].submit();</script>");
        return sbHtml.toString();
    }

    private  String buildHtmlForm(Map<String, String> sParaTemp, String gateway) throws IOException {
        StringBuffer htmlBuf = new StringBuffer();
        htmlBuf.append("<html>");
        htmlBuf.append(" <head><title>sender</title></head>");
        htmlBuf.append(" <body>");
        htmlBuf.append(buildForm(sParaTemp, gateway));
        htmlBuf.append(" </body>");
        htmlBuf.append("</html>");
        return htmlBuf.toString();
    }

    private  Map<String, String> getMapValues(String orderNo ,String bankCode ,String TransAmt) throws Exception {
        Map<String, String> map = new TreeMap<String, String>();
        map.put("requestNo", new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()));//请求流水
        map.put("version", "V1.0");
        map.put("productId", "0208");//产品类型
        map.put("transId", "12");//交易类型
        map.put("merNo", ConfigUtils.getProperty("merchant_no"));//商户号
        map.put("orderDate", new SimpleDateFormat("yyyyMMdd").format(new Date()));//订单时间
        map.put("orderNo",orderNo);//订单号
        map.put("commodityName", "测试商品");
        map.put("transAmt", TransAmt);//交易金额（单位分）
        map.put("bankCode", bankCode);//银行简称
        String webUrl = redisService.get(ConfigNID.WEB_SERVER_URL);
        map.put("returnUrl", webUrl+"/account");// 同步通知地址
        map.put("notifyUrl", webUrl + "/api/notify/hr/doB2CNotify");// 异步通知地址
        map.put("signature", SignUtils.signData(map));//加签数据
        return map;
    }

    /**
     * 华融网银支付银行代码对照
     *
     * @param id
     * @return
     */
    private  String outCode2innerCode4nInepayHR(int id) {
        switch (id) {
            case 2:
                return "ICBC";
            case 3:
                return "ABC";
            case 1:
                return "BOC";
            case 7:
                return "CCB";
            case 4:
                return "BCOM";
            case 10:
                return "CMB";
            case 5:
                return "GDB";
            case 17:
                return "CITIC";
            case 12:
                return "CMBC";
            case 19:
                return "CEB";
            case 28:
                return "PABC";
            case 8:
                return "SPDB";
            case 11:
                return "PSBC";
            case 18:
                return "HXB";
            case 13:
                return "CIB";
            case 20:
                return "BOB";
            case 21:
                return "BOS";
            case 24:
                return "HCCB";
            case 29:
                return "ZSBK";
            case 91:
                return "QDBK";
            case 25:
                return "NBCB";
            case 22:
                return "TCCB";
            case 90:
                return "LZBK";
            case 69:
                return "NJCB";
            case 84:
                return "BJRC";
            case 30:
                return "SHRB";
            default:
                return "";
        }
    }

}
